#pragma once
#include <iostream>
#include<unistd .h>
#include<sys/wait.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<fcntl.h>
#include<string>
#include<cstring>
#include<cstdlib>
#include"../comm/until.hpp"
//只负责编译代码，不负责运行代码
// 这段代码定义了一个命名空间 ns_compiler，
// 在该命名空间下声明了一个 Compiler 类。
// Compiler 类目前只有一个默认构造函数和一个析构函数，
// 都没有实现任何具体的功能。
// 该类的设计意图是作为编译器功能的封装，
// 只负责代码的编译，不负责代码的运行。
// 目前该类是一个空壳，后续可以在其中添加编译相关的方法和成员变量。

namespace ns_compiler{
    //引入路径拼接功能
        using namespace ns_until;
    class Compiler{
        public:
        Compiler(){}   // 默认构造函数
        ~Compiler(){}  // 析构函数

        //输入参数：文件名
        //file_name:abc
        //abc -> ./tmp/abc.cpp
        //abc ->./tmp/abc.exe
        //abc ->./tmp/abc.stderr
        
        static bool Compile(const std::string& file_name){
             pid_t pid = fork();
             if(pid < 0){
                std::cerr << "fork error" << std::endl;//子进程创建失败
                
                return false;
             }
             else if(pid == 0){
                //重定向标准错误输出到文件，文件名是file_name.stderr
                int _stderr = open(pathUntil::Stderr(file_name).c_str(),O_WRONLY|O_CREAT|O_TRUNC,0644);
                //如果重定向失败，则退出
                if(_stderr < 0){
                    std::cerr << "open stderr error" << std::endl;
                    exit(1);
                }
                //重定向标准错误输出到_stderr
                dup2(_stderr,2);
                close(_stderr);
                //  程序替换，并不影响进程的文件描述符表


                //子进程：调用编译器,完成对代码的编译工作
                execlp("g++","-o",pathUntil::Exe(file_name).c_str(),pathUntil::Src(file_name).c_str(),"-std=c++11",nullptr );
                exit(1);
             }
             else{
                waitpid(pid,nullptr,0);
                //父进程：等待子进程结束
                //父进程：检查编译结果
                //如果可执行程序存在，则编译成功
                if(fileUntil:: IsFileExist(pathUntil::Exe(file_name))){
                    return true;
                }
                
             }
             return false;
}
};
}